﻿using System.Globalization;
namespace Plugins.Xml.Serialization
{
    using System;

    public abstract class XmlTypeSerializer<T> : XmlSerializer, IXmlTypeSerializer<T>
    {
        protected XmlTypeSerializer() { }

        public override object Deserialize(string value)
        {
            return (object)Read(value);
        }
        public override string Serialize(object value)
        {
            return Write((T)value);
        }

        protected abstract T Read(string value);
        protected abstract string Write(T value);

        T IXmlTypeSerializer<T>.Read(IXmlPropertyReader reader, string propertyName)
        {
            return Read(reader.Read(propertyName));
        }
        T IXmlTypeSerializer<T>.Read(IXmlPropertyReader reader, int index)
        {
            return Read(reader.Read(index));
        }
        void IXmlTypeSerializer<T>.Write(IXmlPropertyWriter writer, string propertyName, T value)
        {
            writer.Write(propertyName, Write(value));
        }
        void IXmlTypeSerializer<T>.Write(IXmlPropertyWriter writer, int index, T value)
        {
            writer.Write(index, Write(value));
        }

        public override Type RuntimeType { get { return typeof(T); } }
    }

    public sealed class EnumSerializer : XmlTypeSerializer<object>
    {
        private Type _type;
        public EnumSerializer(Type type) { _type = type; }
        protected override object Read(string value)
        {
            return Enum.Parse(_type, value, false);
        }
        protected override string Write(object value)
        {
            return value.ToString();
        }
        public override Type RuntimeType { get { return _type; } }
    }
    public sealed class StringSerializer : XmlTypeSerializer<string>
    {
        private StringSerializer() { }
        private static StringSerializer _instance = new StringSerializer();
        public static StringSerializer Instance { get { return _instance; } }
        protected override string Read(string value)
        {
            return value;
        }
        protected override string Write(string value)
        {
            return value;
        }
    }
    public sealed class Int16Serializer : XmlTypeSerializer<Int16>
    {
        private Int16Serializer() { }
        private static Int16Serializer _instance = new Int16Serializer();
        public static Int16Serializer Instance { get { return _instance; } }
        protected override Int16 Read(string value)
        {
            return Int16.Parse(value, CultureInfo.InvariantCulture);
        }
        protected override string Write(Int16 value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }
    }
    public sealed class Int32Serializer : XmlTypeSerializer<Int32>
    {
        private Int32Serializer() { }
        private static Int32Serializer _instance = new Int32Serializer();
        public static Int32Serializer Instance { get { return _instance; } }
        protected override Int32 Read(string value)
        {
            return Int32.Parse(value, CultureInfo.InvariantCulture);
        }
        protected override string Write(Int32 value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }
    }
    public sealed class Int64Serializer : XmlTypeSerializer<Int64>
    {
        private Int64Serializer() { }
        private static Int64Serializer _instance = new Int64Serializer();
        public static Int64Serializer Instance { get { return _instance; } }
        protected override Int64 Read(string value)
        {
            return Int64.Parse(value, CultureInfo.InvariantCulture);
        }
        protected override string Write(Int64 value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }
    }
    public sealed class DecimalSerializer : XmlTypeSerializer<Decimal>
    {
        private DecimalSerializer() { }
        private static DecimalSerializer _instance = new DecimalSerializer();
        public static DecimalSerializer Instance { get { return _instance; } }
        protected override Decimal Read(string value)
        {
            return Decimal.Parse(value, CultureInfo.InvariantCulture);
        }
        protected override string Write(Decimal value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }
    }
    public sealed class DoubleSerializer : XmlTypeSerializer<double>
    {
        private DoubleSerializer() { }
        private static DoubleSerializer _instance = new DoubleSerializer();
        public static DoubleSerializer Instance { get { return _instance; } }
        protected override double Read(string value)
        {
            return double.Parse(value, CultureInfo.InvariantCulture);
        }
        protected override string Write(double value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }
    }
    public sealed class FloatSerializer : XmlTypeSerializer<float>
    {
        private FloatSerializer() { }
        private static FloatSerializer _instance = new FloatSerializer();
        public static FloatSerializer Instance { get { return _instance; } }
        protected override float Read(string value)
        {
            return float.Parse(value, CultureInfo.InvariantCulture);
        }
        protected override string Write(float value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }
    }
    public sealed class ByteSerializer : XmlTypeSerializer<byte>
    {
        private ByteSerializer() { }
        private static ByteSerializer _instance = new ByteSerializer();
        public static ByteSerializer Instance { get { return _instance; } }
        protected override byte Read(string value)
        {
            return byte.Parse(value, CultureInfo.InvariantCulture);
        }
        protected override string Write(byte value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }
    }
    public sealed class BooleanSerializer : XmlTypeSerializer<bool>
    {
        private BooleanSerializer() { }
        private static BooleanSerializer _instance = new BooleanSerializer();
        public static BooleanSerializer Instance { get { return _instance; } }
        protected override bool Read(string value)
        {
            return bool.Parse(value);
        }
        protected override string Write(bool value)
        {
            return value.ToString(CultureInfo.InvariantCulture);
        }
    }
}
